#include <iostream>
#include <string>
#define bs_list_item bs_ls_item
using std::cout;
using namespace std;

class bs_list {
	public:
		class bs_ls_item {
			public:
				node* nd;
				//node* ft;
				//unsigned int current;
				bs_ls_item* next;
				bs_ls_item* prev;
				bs_list* ls;
				void remove( void );
		};
	private:
		bs_ls_item* db;
		bs_ls_item* current;
	public:
		bs_list( void );								// init, bro
		void add( node* );								// register new node
		void set_current( bs_ls_item* );				// set current flag
		node* get_current( void );						// get current node address
		node* get_by_id( int );							// get node address by ID
		node* get_prev( void );							// get previous node address
		node* get_next( void );							// get next node address
		void remove( node* );							// remove item by address
		bs_list::bs_ls_item* create_item( node* );		// create item dummy
		string to_string( void );						// DEBUG: to cpp string (fo' printin' etc)
		void debug_print( void );						// DEBUG printin'
};

/* ---------------------------------------------------------
   init
--------------------------------------------------------- */
bs_list::bs_list( void ) {
	this->db = NULL;
	this->current = NULL;
}

/* ---------------------------------------------------------
   Register New Node
--------------------------------------------------------- */
void bs_list::add( node* e ) {
	bs_list::bs_ls_item* tmp = this->db;
	if( !tmp ) {
		this->db = this->create_item( e );
		return;
	}
	while( tmp->next != NULL )
		tmp = tmp->next;
	tmp->next = this->create_item( e );
	tmp->next->prev = tmp;
	this->set_current( tmp->next );
}

/* ---------------------------------------------------------
   Create List Item DUMMY
--------------------------------------------------------- */
bs_list::bs_ls_item* bs_list::create_item( node* e ) {
	bs_list::bs_ls_item* tmp = new bs_list::bs_ls_item;
	tmp->nd = e;
	//tmp->ft = f;
	tmp->next = NULL;
	tmp->prev = NULL;
	tmp->ls = this;
	return tmp;
}

/* ---------------------------------------------------------
   Set Current Item
--------------------------------------------------------- */
void bs_list::set_current( bs_ls_item* f ) {
	this->current = f;
}

/* ---------------------------------------------------------
   Get Current Item
--------------------------------------------------------- */
node* bs_list::get_current( void ) {
	return this->current->nd;
}

/* ---------------------------------------------------------
   Get Previous Item
--------------------------------------------------------- */
node* bs_list::get_prev( void ) {
	if( !this->current || !this->current->prev )
		return NULL;
	return this->current->prev->nd;
}

/* ---------------------------------------------------------
   Get Next Item
--------------------------------------------------------- */
node* bs_list::get_next( void ) {
	if( !this->current || !this->current->next )
		return NULL;
	return this->current->next->nd;
}

/* ---------------------------------------------------------
   Get Node address by ID
--------------------------------------------------------- */
node* bs_list::get_by_id( int id = 0 ) {
	int t = 0;
	bs_list::bs_ls_item* tmp = this->db;
	while( tmp != NULL && t != id ) {
		tmp = tmp->next;
		t++;
	}
	return tmp->nd;
}

/* ---------------------------------------------------------
   Remove Item
--------------------------------------------------------- */
void bs_list::remove( node* e ) {
	bs_list::bs_ls_item* tmp = this->db;
	while( tmp->next->nd != e )
		tmp = tmp->next;
	tmp->next->next->prev = tmp;
	tmp->next = tmp->next->next;
	delete tmp->next;
}

/* ---------------------------------------------------------
   debug to_string [for values from 0 to 99]
--------------------------------------------------------- */
string bs_list::to_string( void ) {
	bs_list::bs_ls_item* tmp = this->db;
	string ts;
	ts = "";
	while( tmp != NULL ) {
		if( tmp->nd->value > 9 )
			ts += '0'+tmp->nd->value/10;
		ts += '0'+tmp->nd->value%10; // buggy
		ts += ' ';
		tmp = tmp->next;
	}
	return ts;
}

/* ---------------------------------------------------------
   debug print to console out
--------------------------------------------------------- */
void bs_list::debug_print( void ) {
	bs_list::bs_ls_item* tmp = this->db;
	while( tmp != NULL ) {
		textcolor( this->current == tmp ? 2 : 7 );
		cout << tmp->nd->value << ' ';
		tmp = tmp->next;
	}
	textcolor( 7 );
}


/* ---------------------------------------------------------
   Remove Item From Da List
--------------------------------------------------------- */
void bs_list::bs_ls_item::remove( void ) {
	// Case 1. This is a first element.
	if( this->ls->db == this ) {
		this->ls->db = this->next;
		if( this->ls->current == this )
			this->ls->set_current( this->next );
		delete this;
		return;
	}
	// Case 2. This is the last element.
	if( this->next == NULL ) {
		this->prev->next = NULL;
		if( this->ls->current == this )
			this->ls->set_current( this->prev );
		delete this;
	}
	// Case 3. In Da Middle.
	this->prev->next = this->next;
	this->next->prev = this->prev;
	delete this;
}